
package it.ibs;

import it.enrollement.System_Param;
import it.utils.Hash;
import jpair.api.FieldElement;
import jpair.pairing.BigInt;
import jpair.pairing.Point;

/**
 * ID-based signatures schemes which is derived from the ZSS scheme.
 * 
 * [ZHANG2004EFFICIENT] Zhang, Fangguo and Safavi-Naini, Reihaneh and Susilo, Willy. An efficient signature scheme from bilinear pairings and its applications. Springer. p. 277--290 2004
 *   
 * 
 * @author Francesco Rossi
 * @version 0.1
 * 
 */
public class IB_ZSS {

    System_Param parameter;
    Hash h = new Hash();
    BigInt mod;
    BigInt modf;

    public IB_ZSS(System_Param param) {

        parameter = param;
        mod = parameter.getE().getGroupOrder();
        modf = parameter.getE().getCurve().getField().getOrder();
    }

    public IB_ZSS() {
    }

    /**
     *
     * @param message The message to sign
     * @param SignatureKey The user signature private key
     * @return The message signature
     */
    public Point sign(String message, BigInt kzss) {

        BigInt h1m, den, q;
        Point h1p, signature = null;



        try {

    // H1(m)
            h1m = h.h1(message.getBytes("UTF-8"), parameter.getE().getCurve().getField());
            
          
            // sigma = kblsH1(m)P   
            signature = parameter.getE().getCurve().multiply(parameter.getP(),kzss.multiply(h1m));


        } catch (Exception c) {
            c.printStackTrace();

        }

        return signature;

    }

    /**
     *
     * @param message the message
     * @param identity identity of signer
     * @param signature the signature of message
     * @return true if signature is verified
     */
    public boolean vrf(String message, String ID, Point signature) {
        boolean res = false;
        BigInt h1m, h1ID, h1minv;
        FieldElement pair1;
        Point hp, pp, hpwpub;

        try {

            // H1(ID)
            h1ID = h.h1(ID.getBytes("UTF-8"), parameter.getE().getCurve().getField());
            // H1(m)
            h1m = h.h1(message.getBytes("UTF-8"), parameter.getE().getCurve().getField());

            //( 1 / ( H1(m)))
            h1minv = h1m.modInverse(mod);

            //System.out.println("H1(m)="+h1m);

            // H1(ID)W
            hp = parameter.getE().getCurve().multiply(parameter.getW(), h1ID);

            // System.out.println("H1(m)P="+hp);

            // H1(ID)W + Ppub

            hpwpub = parameter.getE().getCurve().add(hp, parameter.getPpub());

            // (H1(m)P + Ppub)( 1 / ( H1(m)))

            pp = parameter.getE().getCurve().multiply(hpwpub, h1minv);

            pair1 = parameter.getE().compute(pp, signature);


            if (pair1.equals(parameter.getEpp())) {
                res = true;
           System.out.println("Signature Verification = True");

            } else {
                res = false;
               System.out.println("Signature Verification = False");
            }
        } catch (Exception c) {
            c.printStackTrace();

        }

        //    System.out.println("Signature Verification for User "+identity+" ="+res);   

        return res;

    }
}
